FrameLib  0.7
DSP processing with frames of arbitrary timing and length
FrameLib_Multichannel.h
Go to the documentation of this file.
1 
2 #ifndef FRAMELIB_MULTICHANNEL_H
3 #define FRAMELIB_MULTICHANNEL_H
4 
5 #include "FrameLib_Context.h"
6 #include "FrameLib_Object.h"
7 #include "FrameLib_DSP.h"
8 #include <algorithm>
9 #include <vector>
10 
11 // FrameLib_MultiChannel
12 
13 // This abstract class allows mulitchannel connnections and the means to update the network according to the number of channels
14 
15 class FrameLib_MultiChannel : public FrameLib_Object<FrameLib_MultiChannel>
16 {
17 
18 protected:
19 
21 
22 private:
23 
25  typedef std::vector<Connection> MultiChannelOutput;
26 
27 public:
28 
29  // Constructors
30 
31  FrameLib_MultiChannel(ObjectType type, FrameLib_Context context, void *owner, unsigned long nIns, unsigned long nOuts)
32  : FrameLib_Object(type, context, owner, this), mDeleted(false)
33  { setIO(nIns, nOuts); }
34 
35  FrameLib_MultiChannel(ObjectType type, FrameLib_Context context, void *owner) : FrameLib_Object(type, context, owner, this), mDeleted(false) {}
36 
37  // Destructor
38 
40  {
41  mDeleted = true;
43  }
44 
45  // Set Fixed Inputs
46 
47  virtual void setFixedInput(unsigned long idx, double *input, unsigned long size) {};
48 
49  // Audio Processing
50 
51  virtual void blockUpdate(double **ins, double **outs, unsigned long blockSize) {}
52  virtual void reset(double samplingRate, unsigned long maxBlockSize) {}
53 
54  static bool handlesAudio() { return false; }
55 
56 protected:
57 
58  // IO Utilities
59 
60  // Call this in derived class constructors if the IO size is not always the same
61 
62  void setIO(unsigned long nIns, unsigned long nOuts, unsigned long nAudioChans = 0)
63  {
64  FrameLib_Object::setIO(nIns, nOuts, nAudioChans);
65  mOutputs.resize(getNumOuts());
66  }
67 
68  // Query Connections for Individual Channels
69 
70  unsigned long getInputNumChans(unsigned long inIdx);
71  Connection getInputChan(unsigned long inIdx, unsigned long chan);
72 
73  unsigned long getOrderingConnectionNumChans(unsigned long idx);
74  Connection getOrderingConnectionChan(unsigned long idx, unsigned long chan);
75 
76 private:
77 
78  // Deleted
79 
82 
83  // Connection Methods (private)
84 
85  void connectionUpdate(Queue *queue)
86  {
87  if (!mDeleted && inputUpdate())
88  outputUpdate(queue);
89  }
90 
91  virtual bool inputUpdate() = 0;
92  void outputUpdate(Queue *queue);
93 
94 protected:
95 
96  // Outputs
97 
98  std::vector <MultiChannelOutput> mOutputs;
99 
100 private:
101 
102  bool mDeleted;
103 };
104 
105 // ************************************************************************************** //
106 
107 // FrameLib_Pack - Pack Multichannel Signals
108 
110 {
111  enum AtrributeList { kInputs };
112 
113  struct ParameterInfo : public FrameLib_Parameters::Info { ParameterInfo() { add("Sets the number of inputs."); } };
114 
115 public:
116 
117  FrameLib_Pack(FrameLib_Context context, FrameLib_Parameters::Serial *serialisedParameters, void *owner);
118 
119  // Info
120 
121  virtual std::string objectInfo(bool verbose);
122  virtual std::string inputInfo(unsigned long idx, bool verbose);
123  virtual std::string outputInfo(unsigned long idx, bool verbose);
124 
125  virtual const FrameLib_Parameters *getParameters() const { return &mParameters; }
126 
127  virtual FrameType inputType(unsigned long idx) const { return kFrameAny; }
128  virtual FrameType outputType(unsigned long idx) const { return kFrameAny; }
129 
130  virtual void autoOrderingConnections() {}
132 
133 private:
134 
135  virtual bool inputUpdate();
136 
137  FrameLib_Parameters mParameters;
138 
139  static ParameterInfo sParamInfo;
140 };
141 
142 // ************************************************************************************** //
143 
144 // FrameLib_Unpack - Unpack Multichannel Signals
145 
147 {
148  enum AtrributeList { kOutputs };
149 
150  struct ParameterInfo : public FrameLib_Parameters::Info { ParameterInfo() { add("Sets the number of outputs."); } };
151 
152 public:
153 
154  FrameLib_Unpack(FrameLib_Context context, FrameLib_Parameters::Serial *serialisedParameters, void *owner);
155 
156  // Info
157 
158  virtual std::string objectInfo(bool verbose);
159  virtual std::string inputInfo(unsigned long idx, bool verbose);
160  virtual std::string outputInfo(unsigned long idx, bool verbose);
161 
162  virtual const FrameLib_Parameters *getParameters() const { return &mParameters; }
163 
164  virtual FrameType inputType(unsigned long idx) const { return kFrameAny; }
165  virtual FrameType outputType(unsigned long idx) const { return kFrameAny; }
166 
167  virtual void autoOrderingConnections() {}
169 
170 private:
171 
172  virtual bool inputUpdate();
173 
174  FrameLib_Parameters mParameters;
175 
176  static ParameterInfo sParamInfo;
177 };
178 
179 // ************************************************************************************** //
180 
181 // FrameLib_Expand - MultiChannel expansion for FrameLib_Block objects
182 
183 template <class T> class FrameLib_Expand : public FrameLib_MultiChannel
184 {
185 
186 public:
187 
188  FrameLib_Expand(FrameLib_Context context, FrameLib_Parameters::Serial *serialisedParameters, void *owner)
189  : FrameLib_MultiChannel(T::getType(), context, owner), mSerialisedParameters(serialisedParameters->size()), mNumAudioStreams(1)
190  {
191  // Make first block
192 
193  mBlocks.push_back(new T(context, serialisedParameters, owner));
194  mBlocks[0]->setChannel(0);
195 
196  // Copy serialised parameters for later instantiations
197 
198  mSerialisedParameters.write(serialisedParameters);
199 
200  // Set up IO / fixed inputs / audio temps
201 
202  setIO(mBlocks[0]->getNumIns(), mBlocks[0]->getNumOuts(), mNumAudioStreams * mBlocks[0]->getNumAudioChans());
203  mFixedInputs.resize(getNumIns());
204  mAudioTemps.resize(mBlocks[0]->getNumAudioOuts());
205 
206  // Make initial output connections
207 
208  for (unsigned long i = 0; i < getNumOuts(); i++)
209  mOutputs[i].push_back(Connection(mBlocks[0], i));
210 
211  // Check for ordering support
212 
213  if (mBlocks[0]->supportsOrderingConnections())
215 
216  reset(0.0, 4096);
217  }
218 
220  {
221  // Clear connections before deleting internal objects
222 
224 
225  // Delete blocks
226 
227  for (std::vector <FrameLib_Block *> :: iterator it = mBlocks.begin(); it != mBlocks.end(); it++)
228  delete(*it);
229  }
230 
231  // Fixed Inputs
232 
233  virtual void setFixedInput(unsigned long idx, double *input, unsigned long size)
234  {
235  if (idx < mFixedInputs.size())
236  {
237  mFixedInputs[idx].assign(input, input + size);
238  updateFixedInput(idx);
239  }
240  }
241 
242  // Audio Processing
243 
244  // FIX - allow the expand object to write/read different blocks from different audio IO (auto multichannel)
245 
246  virtual void blockUpdate(double **ins, double **outs, unsigned long blockSize)
247  {
248  unsigned long internalNumIns = mBlocks[0]->getNumAudioIns();
249  unsigned long internalNumOuts = mBlocks[0]->getNumAudioOuts();
250 
251  // Allocate temporary memory
252 
253  if (internalNumOuts)
254  mAudioTemps[0] = alloc<double>(blockSize * internalNumOuts);
255  for (unsigned long i = 1; i < internalNumOuts; i++)
256  mAudioTemps[i] = mAudioTemps[0] + (i * blockSize);
257 
258  // Zero outputs
259 
260  for (unsigned long i = 0; i < getNumAudioOuts(); i++)
261  std::fill_n(outs[i], blockSize, 0.0);
262 
263  // Process and sum to outputs
264 
265  for (unsigned long i = 0; i < mBlocks.size(); i++)
266  {
267  unsigned long inStreamOffset = internalNumIns * (i % mNumAudioStreams);
268  unsigned long outStreamOffset = internalNumOuts * (i % mNumAudioStreams);
269 
270  mBlocks[i]->blockUpdate(ins + inStreamOffset, &mAudioTemps[0], blockSize);
271 
272  for (unsigned long j = 0; j < internalNumOuts; j++)
273  for (unsigned long k = 0; k < blockSize; k++)
274  outs[outStreamOffset + j][k] += mAudioTemps[j][k];
275  }
276 
277  // Release temporary memory and clear allocator
278 
279  if (getNumAudioOuts())
280  dealloc(mAudioTemps[0]);
281 
282  clearAllocator();
283  }
284 
285  // Reset
286 
287  virtual void reset(double samplingRate, unsigned long maxBlockSize)
288  {
289  mSamplingRate = samplingRate;
290  mMaxBlockSize = maxBlockSize;
291 
292  for (std::vector <FrameLib_Block *> :: iterator it = mBlocks.begin(); it != mBlocks.end(); it++)
293  (*it)->reset(samplingRate, maxBlockSize);
294  }
295 
296  // Handles Audio
297 
298  static bool handlesAudio() { return T::handlesAudio(); }
299 
300  virtual std::string objectInfo(bool verbose) { return mBlocks[0]->objectInfo(verbose); }
301  virtual std::string inputInfo(unsigned long idx, bool verbose) { return mBlocks[0]->inputInfo(idx, verbose); }
302  virtual std::string outputInfo(unsigned long idx, bool verbose) { return mBlocks[0]->outputInfo(idx, verbose); }
303  virtual std::string audioInfo(unsigned long idx, bool verbose) { return mBlocks[0]->audioInfo(idx, verbose); }
304 
305  virtual FrameType inputType(unsigned long idx) const { return mBlocks[0]->inputType(idx); }
306  virtual FrameType outputType(unsigned long idx) const { return mBlocks[0]->outputType(idx); }
307 
308  virtual const FrameLib_Parameters *getParameters() const { return mBlocks[0]->getParameters(); }
309 
310  virtual void autoOrderingConnections()
311  {
312  for (std::vector <FrameLib_Block *> :: iterator it = mBlocks.begin(); it != mBlocks.end(); it++)
313  (*it)->autoOrderingConnections();
314  }
315 
317  {
318  for (std::vector <FrameLib_Block *> :: iterator it = mBlocks.begin(); it != mBlocks.end(); it++)
319  (*it)->clearAutoOrderingConnections();
320  }
321 
322 private:
323 
324  // Update Fixed Inputs
325 
326  void updateFixedInput(unsigned long idx)
327  {
328  for (unsigned long i = 0; i < mBlocks.size(); i++)
329  mBlocks[i]->setFixedInput(idx, &mFixedInputs[idx][0], mFixedInputs[idx].size());
330  }
331 
332  // Update (expand)
333 
334  virtual bool inputUpdate()
335  {
336  // Find number of channels (always keep at least one channel)
337 
338  unsigned long nChannels = 1;
339  unsigned long cChannels = mBlocks.size();
340 
341  for (unsigned long i = 0; i < getNumIns(); i++)
342  if (getInputNumChans(i) > nChannels)
343  nChannels = getInputNumChans(i);
344 
345  nChannels = std::max(nChannels, mNumAudioStreams);
346 
347  // Resize if necessary
348 
349  bool numChansChanged = nChannels != cChannels;
350 
351  if (numChansChanged)
352  {
353  // Change the number of hosted blocks
354 
355  if (nChannels > cChannels)
356  {
357  mBlocks.resize(nChannels);
358 
359  for (unsigned long i = cChannels; i < nChannels; i++)
360  {
361  mBlocks[i] = new T(getContext(), &mSerialisedParameters, getOwner());
362  mBlocks[i]->setChannel(i);
363  mBlocks[i]->reset(mSamplingRate, mMaxBlockSize);
364  }
365  }
366  else
367  {
368  for (unsigned long i = nChannels; i < cChannels; i++)
369  delete mBlocks[i];
370 
371  mBlocks.resize(nChannels);
372  }
373 
374  // Redo output connection lists
375 
376  for (unsigned long i = 0; i < getNumOuts(); i++)
377  mOutputs[i].clear();
378 
379  for (unsigned long i = 0; i < getNumOuts(); i++)
380  for (unsigned long j = 0; j < nChannels; j++)
381  mOutputs[i].push_back(Connection(mBlocks[j], i));
382 
383  // Update Fixed Inputs
384 
385  for (unsigned long i = 0; i < getNumIns(); i++)
386  updateFixedInput(i);
387  }
388 
389  // Make input connections
390 
391  for (unsigned long i = 0; i < getNumIns(); i++)
392  {
393  if (getInputNumChans(i))
394  {
395  for (unsigned long j = 0; j < nChannels; j++)
396  {
397  Connection connection = getInputChan(i, j % getInputNumChans(i));
398  mBlocks[j]->addConnection(connection.mObject, connection.mIndex, i);
399  }
400  }
401  else
402  {
403  for (unsigned long j = 0; j < nChannels; j++)
404  mBlocks[j]->deleteConnection(i);
405  }
406  }
407 
408  // Clear ordering connections
409 
410  for (unsigned long j = 0; j < nChannels; j++)
411  mBlocks[j]->clearOrderingConnections();
412 
413  // Make ordering connections
414 
415  for (unsigned long i = 0; i < getNumOrderingConnections(); i++)
416  {
418  {
419  for (unsigned long j = 0; j < nChannels; j++)
420  {
422  mBlocks[j]->addOrderingConnection(connection.mObject, connection.mIndex);
423  }
424  }
425  }
426 
427  return numChansChanged;
428  }
429 
430  // Member Variables
431 
432  FrameLib_Parameters::AutoSerial mSerialisedParameters;
433 
434  std::vector <FrameLib_Block *> mBlocks;
435  std::vector <std::vector <double> > mFixedInputs;
436 
437  unsigned long mNumAudioStreams;
438  unsigned long mMaxBlockSize;
439  double mSamplingRate;
440 
441  std::vector<double *> mAudioTemps;
442 };
443 
444 #endif
ObjectType
Definition: FrameLib_Types.h:24
virtual std::string objectInfo(bool verbose=false)
Definition: FrameLib_Object.h:160
void deleteConnection(unsigned long inIdx)
Definition: FrameLib_Object.h:200
Definition: FrameLib_Multichannel.h:109
unsigned long getNumOuts() const
Definition: FrameLib_Object.h:138
unsigned long getInputNumChans(unsigned long inIdx)
Definition: FrameLib_Multichannel.cpp:8
Definition: FrameLib_Parameters.h:21
virtual void reset(double samplingRate, unsigned long maxBlockSize)
Definition: FrameLib_Multichannel.h:287
void setIO(unsigned long nIns, unsigned long nOuts, unsigned long nAudioChans=0)
Definition: FrameLib_Multichannel.h:62
Definition: FrameLib_Context.h:10
static bool handlesAudio()
Definition: FrameLib_Multichannel.h:54
static bool handlesAudio()
Definition: FrameLib_Multichannel.h:298
virtual FrameType inputType(unsigned long idx) const
Definition: FrameLib_Multichannel.h:164
Definition: FrameLib_Parameters.h:34
void dealloc(U *&ptr)
Definition: FrameLib_Object.h:340
virtual std::string outputInfo(unsigned long idx, bool verbose)
Definition: FrameLib_Multichannel.h:302
unsigned long getNumAudioChans() const
Definition: FrameLib_Object.h:141
virtual void clearAutoOrderingConnections()
Definition: FrameLib_Multichannel.h:168
virtual void autoOrderingConnections()
Definition: FrameLib_Multichannel.h:167
virtual std::string objectInfo(bool verbose)
Definition: FrameLib_Multichannel.h:300
virtual void blockUpdate(double **ins, double **outs, unsigned long blockSize)
Definition: FrameLib_Multichannel.h:51
virtual std::string outputInfo(unsigned long idx, bool verbose=false)
Definition: FrameLib_Object.h:162
unsigned long mIndex
Definition: FrameLib_Object.h:103
ObjectType getType() const
Definition: FrameLib_Object.h:125
virtual void autoOrderingConnections()
Definition: FrameLib_Multichannel.h:130
Definition: FrameLib_Object.h:91
void clearConnections()
Definition: FrameLib_Object.h:262
U * mObject
Definition: FrameLib_Object.h:102
FrameLib_Object::UntypedConnection< FrameLib_Block > Connection
Definition: FrameLib_Multichannel.h:20
virtual std::string audioInfo(unsigned long idx, bool verbose)
Definition: FrameLib_Multichannel.h:303
virtual void clearAutoOrderingConnections()
Definition: FrameLib_Multichannel.h:316
Definition: FrameLib_Multichannel.h:15
Definition: FrameLib_Object.h:97
void clearAllocator()
Definition: FrameLib_Object.h:346
virtual const FrameLib_Parameters * getParameters() const
Definition: FrameLib_Multichannel.h:308
virtual FrameType outputType(unsigned long idx) const
Definition: FrameLib_Multichannel.h:128
virtual std::string inputInfo(unsigned long idx, bool verbose=false)
Definition: FrameLib_Object.h:161
Connection getInputChan(unsigned long inIdx, unsigned long chan)
Definition: FrameLib_Multichannel.cpp:16
Definition: FrameLib_Multichannel.h:183
virtual void setFixedInput(unsigned long idx, double *input, unsigned long size)
Definition: FrameLib_Multichannel.h:233
FrameLib_Context getContext() const
Definition: FrameLib_Object.h:129
virtual void blockUpdate(double **ins, double **outs, unsigned long blockSize)
Definition: FrameLib_Multichannel.h:246
void clearOrderingConnections()
Definition: FrameLib_Object.h:254
FrameLib_Expand(FrameLib_Context context, FrameLib_Parameters::Serial *serialisedParameters, void *owner)
Definition: FrameLib_Multichannel.h:188
bool supportsOrderingConnections() const
Definition: FrameLib_Object.h:299
virtual FrameType inputType(unsigned long idx) const
Definition: FrameLib_Multichannel.h:127
virtual FrameType outputType(unsigned long idx) const
Definition: FrameLib_Multichannel.h:165
size_t blockSize(void *ptr)
Definition: FrameLib_Memory.cpp:23
Definition: FrameLib_Parameters.h:153
void enableOrderingConnections()
Definition: FrameLib_Object.h:331
virtual const FrameLib_Parameters * getParameters() const
Definition: FrameLib_Multichannel.h:125
unsigned long getOrderingConnectionNumChans(unsigned long idx)
Definition: FrameLib_Multichannel.cpp:21
FrameLib_MultiChannel(ObjectType type, FrameLib_Context context, void *owner)
Definition: FrameLib_Multichannel.h:35
virtual std::string inputInfo(unsigned long idx, bool verbose)
Definition: FrameLib_Multichannel.h:301
virtual ~FrameLib_MultiChannel()
Definition: FrameLib_Multichannel.h:39
Definition: FrameLib_Types.h:25
unsigned long getNumOrderingConnections() const
Definition: FrameLib_Object.h:300
void setIO(unsigned long nIns, unsigned long nOuts, unsigned long nAudioChans=0)
Definition: FrameLib_Object.h:320
std::vector< MultiChannelOutput > mOutputs
Definition: FrameLib_Multichannel.h:98
virtual FrameType outputType(unsigned long idx) const
Definition: FrameLib_Multichannel.h:306
virtual void clearAutoOrderingConnections()
Definition: FrameLib_Multichannel.h:131
unsigned long getNumAudioOuts() const
Definition: FrameLib_Object.h:140
virtual FrameType inputType(unsigned long idx) const
Definition: FrameLib_Multichannel.h:305
Definition: FrameLib_Parameters.h:129
Connection getOrderingConnectionChan(unsigned long idx, unsigned long chan)
Definition: FrameLib_Multichannel.cpp:29
FrameType
Definition: FrameLib_Types.h:25
Definition: FrameLib_Multichannel.h:146
virtual void setFixedInput(unsigned long idx, double *input, unsigned long size)
Definition: FrameLib_Multichannel.h:47
virtual void autoOrderingConnections()
Definition: FrameLib_Multichannel.h:310
virtual void reset(double samplingRate, unsigned long maxBlockSize)
Definition: FrameLib_Multichannel.h:52
FrameLib_Queueable< FrameLib_MultiChannel >::Queue Queue
Definition: FrameLib_Object.h:115
unsigned long getNumIns() const
Definition: FrameLib_Object.h:137
FrameLib_MultiChannel(ObjectType type, FrameLib_Context context, void *owner, unsigned long nIns, unsigned long nOuts)
Definition: FrameLib_Multichannel.h:31
~FrameLib_Expand()
Definition: FrameLib_Multichannel.h:219
virtual const FrameLib_Parameters * getParameters() const
Definition: FrameLib_Multichannel.h:162
void * getOwner() const
Definition: FrameLib_Object.h:133